/* qHtml.js (qJSLib)
 
    @Summary    : Set of HTML Building Code
    @Author     : Timothy C. Quinn
    @License    : http://www.opensource.org/licenses/mit-license.php
  
    @Dependencies:
     - qCore.js (qJSLib)
   
    @Notes:
     - (none)
   
    @Todo:
     - 
*/

qHtml = {
  // Position Constants
	 POS_TL: "POS_TL"
    ,POS_TR: "POS_TR"
    ,POS_BR: "POS_BR"
    ,POS_BL: "POS_BL"
	
  /* Html Tag Constants */
  /* General */
  	,IMG: 		{tag: "img"}
  	,DIV:       {tag: "div"}
  	,FAKE_Link: {tag: "b", _class:"anc_option anc_unselected"}
  	
  /* Tables */
    ,TABLE:		{tag: "table", _cellpadding: 0, _cellspacing: 0, _border: 0, nl: true, open: true}
    ,TD: 		{tag: "td"}
    ,TR: 		{tag: "tr", nl: true}
    
  /* Forms */  
    ,FORM: {tag: "form", _action: "post", _enctype: "multipart/form-data", _onsubmit: "return false", nl: true}
    ,TB:   {tag: "input", _type: "text", nl: true}
    ,CB:   {tag: "input", _type: "checkbox", nl: true}
    ,ML:   {tag: "textarea", nl: false}// Make sure nl=true!
    ,DD: 	{tag: "select", nl: true}
    
    ,qAnc: function qAnc(sId,sT){ return "<span id=\""+sId+"\" style='text-decoration: none; color: #0000CC; cursor: "+(is.moz?"pointer":"hand")+"' onmouseover='this.style.color=\"#CC0000\"' onmouseout='this.style.color=\"#0000CC\"'>"+sT+"</span>"}//.format(sID,(is.moz?"pointer":"hand"),sT) }
  
  /* Html Build Helpers */
  /* Tables  */  
    ,tblHd: function qhtml_tblHd(j){
        var t=this,v,iBr;j=j?j:{}
        iBr=(isNum(j.br)||j.br>=0?j.br:0)
//_w.__dbg=true
//pc(mkE(t.TABLE, j))
//_w.__dbg=false        
        return ("\n"+"<br>".repeat(iBr))+mkE(j.table||t.TABLE, j)
    }
    ,tblFt: function qhtml_tblFt(){return "\n</table>"}
    /* Note: use $h to set Text */
    ,tblHdrRow: function qhtml_tblHdrRow(sText,jTd,jTr){
        var t=this,v;
        jTd=jTd?jTd:{}
        jTd._class=(isDef(v=jTd._class))?v:"head"
        jTd._colspan=(isDef(v=jTd._colspan))?v:99
        jTr=jTr?jTr:{}
        return t.tblRow("\n  "+mkE(sText,t.TD, jTd),jTr)
    }
    ,tblRow: function qhtml_tblRow(s,j){
        var t=this,v;j=j?j:{}
        return mkE(s,t.TR, j)
    }
    ,tblCell: function qhtml_tblCell(s,j){
        var t=this,v;j=j?j:{}
        return mkE(s,t.TD, j)
    }
    
    ,tblCells: function qhtml_tblCells(){
        var t=this,v,args=arguments,s="",sCnt,j;
        for(var i=0;i<args.length;i++){j=args[i]
        	sCnt=isDef(v=j.$h)?v:"&nbsp;"
            s+="\n  "+mkE(sCnt, t.TD, j)
        }
        return s
    }
    ,tblIndentTable: function qhtml_tblIndentTable(sL,sV){
        return "\n<table border=0 cellpadding=0 cellspacing=0 width=100%><tr><td class=LblLT>"+sL+"</td></tr><tr><td class=Att style=\"padding-left: 10px\">"+sV+"&nbsp;</td></tr></table>"
    }

  /* END Tables  */ 

	,curveBox: function qhtml_curveBox(sH,j){
		var s="",sImg,sBgC,iR,c=j.corners||[1,1,1,1];
		sBgC=j.bgColor;iR=j.radius;sImg=imagePath+"rc_"+sBgC+"_"+iR+"."+(is.ie?"gif":"png");
		s+="<table class='qCB' "+(j.width?"width="+j.width:"")+" qCBStats='{radius: "+iR+", bgColor: "+sBgC+"}' cellpadding='0' cellspacing='0' style='border-collapse:collapse;'><tr>";
		_C(0,0,c[0],c[1],c[3]);_O();_C(-(iR),0,c[1],c[0],c[2]);s+="</tr><tr>";_O();s+="<td style='background:#"+sBgC+" none repeat scroll 0% "+(j.font?"; font: "+j.font:"")+"'>"+sH+"</td>";_O();;s+="</tr><tr>";
		_C(0,-(iR),c[3],c[2],c[0]);_O();_C(-(iR),-(iR),c[2],c[3],c[1]);s+="</table>";
		return s;
		function _C(x,y,b,bH,bW){s+="<td class='qRCC' style='height:"+(b?iR:!bH?2:iR)+"px;width:"+(b?iR:!bW?2:iR)+"px; "+(b?"background-position: "+x+"px "+y+"px; background-image: url(\""+sImg+"\")":"background:#"+sBgC)+";'></td>"}
		function _O(){s+="<td class='qRCO' style='background:#"+sBgC+" none repeat scroll 0%'></td>"}
	}

  /* Forms */
  /* . Form */
    ,frmForm: function qhtml_frmForm(sFormName, j) {
        var t=this;j=j?j:{}
        j._name = sFormName
        if(isUndef(sFormName))qErr("Form Name (sFormName) is required!")
        return mkE(t.FORM, j)
    }
  /* . Text Box */
    ,frmTB: function qhtml_frmTB(sName, sVal, j) {
        var t=this;j=t.addFormElemNVI(j,sName,sVal)

        if(!isNum(j._size))j._size=15;
if(_w.__DBG){
    pc(
         "\n j:\n"+s$.pad(q$.dump(j))
        +"\n args:\n"+s$.pad(q$.dumpArgs())
//        +"\n stack:\n"+s$.pad(getStackTrace())
//        +"\n mkE:\n"+s$.pad(mkE(t.TB, j))
    );
}
        return mkE(t.TB, j)
    }
    
  /* . Check Box */
    ,frmCB: function qhtml_frmCB(sName, bChecked, j) {
        var t=this;j=t.addFormElemNVI(j,sName)
        if(bChecked){j._checked=true}// <~ Note: just Checked is fine too
        return mkE(t.CB, j)
    }
    
  /* . Multi-Line */
    ,frmML: function qhtml_frmML(sName, sVal, j) {
        var t=this,v;j=t.addFormElemNVI(j, sName)
        j._cols=isNum(v=j._cols)?v:60
        j._rows=isNum(v=j._rows)?v:4
        sVal=sVal.cleanForHtml()
        return mkE(sVal,t.ML, j)
    }
    
  /* . Drop-Down */
    ,MK_bad: "__bad"
    ,DD_val: 0
    ,DD_lbl: 1
    ,DD_sel: 2
    ,frmDD: function qhtml_frmDD(sName, aDDRng, j) {
        var t=this,v,args=arguments,sb=new StringBuffer(),sOC,sEC,bC,aB;j=j?j:{}
        if(bC=j.useColor){sOC=(v=j.oddCol)?v:"#FFFFFF",sEC=(v=j.evnCol)?v:"#EBEBEB"}
//debug(q$.dumpArgs())
//pc("aRange.length = "+aRange.length)
        
	 // Process Blank Value
        j=t.addFormElemNVI(j, sName)
        j._size=isNum(v=j._size)?v:1
        
        for (var i=0; i<aDDRng.length; i++){r=aDDRng[i]
        	sb.a("\n  <option value=\"").a(r[t.DD_val]).a("\"")
        	if(r[t.DD_sel])sb.a(" selected")
        	if(bC)sb.a(" style=\"background-color: ").a((i%2)?sOC:sEC).a("\"")
        	sb
        	   .a(">"
        	  ).a(r[t.DD_lbl]
        	  ).a("</option>"
        	)
        }
        if(aB=aDDRng[t.MK_bad]){
        	
        }
        return (
        	mkE(sb.a("\n").ts(),t.DD, j)
        	+((v=aDDRng[t.MK_bad])?"<div>(Warning - stored value(s) not found: '"+v.join(", ")+"')</div>":"")
        )
    }
   // Builds [[Value,Label,Selected],...]
    ,buildDDRng: function qhtml_buildDDRng(oSel, aLbls, aVals, jOpts){
    	var t=this,aSel=isArray(oSel)?oSel:[oSel],aRet=[],aTmp,args=arguments,aBad=[],bF;
    	jOpts=jOpts||{};
    	if(args.length==2){aVals=aLbls}
//pc(
//	"\n args.length = "+args.length
//   +"\n args:\n"+s$.pad(q$.dumpArgs())
//   +"\n jOpts:\n"+s$.pad(q$.dumpObj(jOpts))
//   +"\n stack:\n"+s$.pad(getStackTrace())
//)
      // Remove Blanks & Clean Sel
    	aTmp=[];for(var i=0;i<aSel.length;i++){
    		s=s$(aSel[i]).trim()
    		if(!(s==="")){
    			bF=false
				for (var j=0;j<aVals.length;j++){
					if(s$(aVals[j])===s){bF=true; break;}
				}
				if(bF){aTmp.p(s)}else {aBad.p(s)}
    		}
    	};aSel=aTmp
//pc(
//	"\n HERE"
//   +"\n jOpts.addBlank = "+jOpts.addBlank
//   +"\n jOpts:\n"+s$.pad(q$.dumpObj(jOpts))
//)   	
    	if(aSel.length==0||jOpts.addBlank){
//    		aSel.p("")
	 		if( !(aVals[0]==="") ){
		 		aVals=[""].concat(aVals)
		 		aLbls=[""].concat(aLbls)
		 	}
    	}
    	
        aTmp=[];for (var i=0;i<aLbls.length;i++){
        	sVal=s$(aVals[i]).trim()
        	aTmp=[sVal, s$(aLbls[i]).trim(), aSel.has(sVal)]
        	aRet.p(aTmp)
        	aRet["v_"+sVal] = aTmp
        }
        
        if(aBad.length>0)aRet[t.MK_bad]=aBad
        return aRet
    }
    ,getDDRngSel: function getDDRngSel(aDDRng){
    	var t=this,aSel=[],r,v;
    	for(var i=0;i<aDDRng.length;i++){r=aDDRng[i];
    		if(r[t.DD_sel] && !( (v=r[t.DD_val]) === "") )aSel.p(r[t.DD_val])
    	}
    	return aSel
    }
    ,rebuildDD: function rebuildDD(o,aDDRng,j) {//aDDRng = buildDDRng() ret
	  var v,r,sOC,sEC,bC=j.useColor;
	  if(bC){sOC=(v=j.oddCol)?v:"#FFFFFF",sEC=_(v=j.evnCol)?v:"#EBEBEB"}
	  DDWarn(o);if(!isArray(aDDRng)) {debugErr("aDDRng must be Array")}
	  o.options.length=0
	  for(var i=0;i<aDDRng.length;i++){r=aDDRng[i];
		  o.options[i]=new Option(r[1],r[0],false,r[2]);
		  if(bC){o.options[i].style.backgroundColor=i%2?sOC:sEC}
	  }
	}
	
  /* MultiSelectList 
  	 . Options (j):
  	 .. autoAdd <~ Will auto add items to selected on change of dd
  	 .. ddOps <~ Pass args to creation of DD (mkE)
  	 . Todo:
  	 .. Add Ordering Capability
  */
    ,MultiSelectList: {
    	 MK_divMainBase: "divDDM_Main_"
    	,MK_tdAddBase: "tdDDM_Main_"
    	,HTML_spanAddRem: "<span onmouseover=\"this.style.color='navy'\" onmouseout=\"this.style.color='#999999'\" style='font: regular 105% tahoma; color: #999999; cursor: pointer; cursor: hand; ~1'"
    	,priv_data: {}
    	,build: function msl_build(sName, aDDRng, j){
    		var t=this;j=j?j:{}
    		t.priv_data[sName]={ddRng: aDDRng, j: j}
    		return t.priv_rebuild(sName, true)
    	}
    	,priv_rebuild: function msl_priv_rebuild(sName, bFirst){
	        var t=this,h=qHtml,v,sb=new StringBuffer(),sOpts="",r,aTmp,sOC,sEC,bC,aDDRng, oRngInfo,j,oDiv;
//pc("CALLED")
	      // Get Range Data
	        oRngInfo=t.getRngInfo(sName)
	        aDDRng=oRngInfo.ddRng
	        j=oRngInfo.j||{};j.ddOps=(v=j.ddOps)?v:{}
	        sb.a("<div id='").a(t.MK_divMainBase).a(sName).a("'><table cellpadding=0px cellspacing=2px style='font-weight: bold; width: 5px'>")
	        aTmp=[]
//pc(
//	"\n aDDRng:\n"+s$.pad(q$.dumpJson(aDDRng))
//)
	        for(var i=0;i<aDDRng.length;i++){r=aDDRng[i]
	        	if(r[h.DD_sel] && !(r[h.DD_val]==="")){
	        		sb
	        			.a( "<tr><td style='width: 0%' title='Click to Remove Entry'>"
	        		   ).a( t.HTML_spanAddRem//.format("font-style: italic")
	        		   		).a(" onclick=\"qHtml.MultiSelectList.e_remove_click("
	        		   			).a( "'").a(sName	).a("'"
	        		   		    ).a(",'").a(r[0]	).a("'"
	        		   		).a(")"
	        		   		).a("\">[x]</span>"
	        		   ).a( "</td><td style='white-space: nowrap'>"
	        		   ).a( r[1]
					   ).a( "</td></tr>"
	        		   ).a( 
	        		);	
	        	} else {
	        		aTmp.p(r)
	        	}
	    	}
//pc(
//	"\n aTmp.length = "+aTmp.length
//   +"\n aTmp:\n"+s$.pad(q$.dump(aTmp))
//)
	 		if(aTmp.length > 0 && aTmp[0][h.DD_val]===""){
		 		aTmp[0][h.DD_sel]=true
		 	}else{
		 		aTmp=[["","",true]].concat(aTmp)
		 	}
		 	
//pc(
//	"\n aTmp.length = "+aTmp.length
//   +"\n aTmp:\n"+s$.pad(q$.dump(aTmp))
//)
			if(aTmp.length>1){
				j.ddOps._onchange="qHtml.MultiSelectList.e_dd_onchange(event,this,'"+sName+"')"
				
//pc(
//	"\n DD Html:\n"+s$.pad(h.frmDD(sName, aTmp, j.ddOps))
//)
				
	    		sb
	    			.a( "<tr><td colspan=2>"
	    		   ).a( h.frmDD(sName, aTmp, j.ddOps)
	    		   ).a( "</td><td id='").a(t.MK_tdAddBase).a(sName).a("' style='display: none'>"
	    		   ).a( t.HTML_spanAddRem
	    		   		).a(" onclick=\"qHtml.MultiSelectList.e_add_click('").a(sName).a("')\""
	    		   ).a( "> &lt;-Add</span></td></tr>"
	    		);
	    	} else {
	    		if(aDDRng.length == 1)
	    			sb.a("<tr><td colspan=2 style='color: #999999; text-align: left'>(Range&nbsp;is&nbsp;Empty!)"+(h.frmDD(sName, [], {_style: 'display: none'}))+"</td></tr>")	
	    		else
	    			sb.a("<tr><td colspan=2 style='color: #999999; text-align: left'>(all selected)</td></tr>")	
	    	}
    		sb.a("\n</table></div>")
//pc(
//	"\n h.MK_bad = "+h.MK_bad
//   +"\n aDDRng[h.MK_bad] = "+aDDRng[h.MK_bad]
//)
    		if(v=aDDRng[h.MK_bad])
    			sb.a("<div style='color: gray'>(Warning - stored value(s) not found in options list: '"+v.join(", ")+"')</div>")
//pc(
//	"\n sb:\n"+s$.pad(sb.ts())
//)
    		if(bFirst){
    			return sb.ts()
            }else{
    			oDiv = agetElem(t.MK_divMainBase+sName)
    			oDiv.parentNode.innerHTML=sb.ts()
    		}

    	}
    	,getRngInfo: function msl_getRngInfo(sName){
    		var t=this, oRngInfo;
    		oRngInfo = agetParam_json("msl.priv_data", t.priv_data, sName, true);
    		return oRngInfo;
    	}
    	,getSelected: function msl_getSelected(sName){
    		var t=this, oDD, sVal, oRngInfo,aDDRng,r
    		try {
    			oRngInfo=t.getRngInfo(sName)
    			aDDRng=oRngInfo.ddRng
				aSel=qHtml.getDDRngSel(aDDRng)
				return aSel
    		}catch(x){qErr(x,{varDump: {sName: sName}})}
    	}
    	,e_dd_onchange: function msl_e_dd_onchange(e, oDD, sName){
    		var t=this, oRngInfo,aDDRng,r,sH,bDisp,oTD,j,f;
//pc("called")
    		try {
    			oRngInfo=t.getRngInfo(sName)
    			j=oRngInfo.j
    			oDD=agetElem(sName)
    			oTD=agetElem(t.MK_tdAddBase+sName)
    			if(j.autoAdd){
					t.e_add_click(sName)
	    		} else {
	    			bDisp=!((sVal=getDDValue(oDD).trim())==="")
	    			oTD.style.display=bDisp?"":"none"
	    		}
	    	  // Call onchange Handler
	    		if(isFunc(f=j.hChange)){f(e,oDD,j.extId)}
    		}catch(x){qErr(x,{varDump: {args: q$.dumpArgs()}})}
    	}
    	,e_remove_click: function msl_e_remove_click(sName, sVal){
    		var t=this, oRngInfo,aDDRng,r,j;
    		try {
	    		oRngInfo=t.getRngInfo(sName)
	    		j=oRngInfo.j
	    		aDDRng=oRngInfo.ddRng
	    		r=aDDRng["v_"+sVal]
	    		r[2]=false
	    		t.priv_rebuild(sName, false)

	    	  // Call onchange Handler
	    		if(isFunc(f=j.hChange)){f({},{},j.extId)}
//pc(
//	"\n t.getSelected(sName) = "+t.getSelected(sName)
//)
	    		
	    	}catch(x){qErr(x,{varDump: {sName: sName, sVal: sVal}})}
    	}
    	,e_add_click: function msl_e_add_click(sName){
    		var t=this, oDD, sVal, oRngInfo,aDDRng,r
    		try {
    			oDD=agetElem(sName)
    			oRngInfo=t.getRngInfo(sName)
    			aDDRng=oRngInfo.ddRng
	    		if((sVal = getDDValue(oDD).trim())===""){
	    			pc("Blank - Exiting")
	    			return
	    		}
	    		r=aDDRng["v_"+sVal]
//pc(
//	"\n sName = "+sName
//   +"\n sVal = "+sVal
//   +"\n r:\n"+s$.pad(q$.dumpJson(r))
//   +"\n aDDRng:\n"+s$.pad(q$.dumpJson(aDDRng))
//)
	    		r[2]=true
	    		t.priv_rebuild(sName, false)
    		}catch(x){qErr(x,{varDump: {sName: sName}})}
    	}
    }

    
    
  /* . private */
    ,addFormElemNVI: function qhtml_addFormElemNVI(j, sName, sVal){
        var t=this;j=j?j:{}
        j._name=sName
        if(isDef(sVal)){j._value=sVal;}
        if(!j._id){j._id=sName}
        return j
    }
    
  /* END Forms */
    
    
    
  /* General Helpers */
    ,insertBreaks: function qhtml_insertBreaks(sText, iCh){
    	var sb = new StringBuffer(), aSp, iCtr=0,v;
    	aSp = sText.split(" ");
    	for(var i=0;i<aSp.length;i++){v=aSp[i];
    		if(iCtr>=iCh){
    			sb.a("<br>");
    			iCtr=0;
//pc("iCtr = "+iCtr)
    		} else {
    			iCtr+=v.length;
//pc("iCtr = "+iCtr)
    			if(i>0)sb.a(" ");
    		}
    		sb.a(v)
    	}	
    	return sb.ts();
    }
    
   ,qButton: {
		build: function qButton_build(oElem, sText, sImg, fClick){
			var t=this,oBt
			oElem.innerHTML=(
				"<button "
					+" style='color: #555; background: #dddecb; font: bold 12px arial; border: 1px solid #aaa; cursor: hand; cursor: pointer; padding: "+(is.moz?2:0)+"px 2px "+(is.moz?2:0)+"px 2px; width:auto; overflow:visible;' "
					+" onmouseover='var o=this,os=o.style; o._bk=os.backgroundColor;os.backgroundColor=\"#cccecb\"' "
					+" onmouseout='var o=this,os=o.style; os.backgroundColor=o._bk' "
				+">"// width: "+(iWidth)+"px'
				   +"<img"
				   		+" src='"+sImg+"' height='16px' width='16px' "
				   		+" style='text-align: top; position: absolute; float: left'"
			   	+">"
				+"<span style='margin-left: 20px'>"+sText+"</span>"
				+"</button>"	
			)
			oBt=oElem.getElementsByTagName("button")[0]
			qSetOpacity(oBt, 0.9)
			if(isFunc(fClick))assignEventListener(oBt, "click", fClick)
			assignEventListener(oBt, "mouseover", t.e_mouseover)
			assignEventListener(oBt, "mouseout", t.e_onmouseout)
		}
		,e_mouseover: function qButton_e_mouseover(e){e=getEvent(e);
			var o=e.target,os=o.style; 
			o._bk=os.backgroundColor;os.backgroundColor="#cccecb"
			qSetOpacity(o, 1)
		}
		,e_onmouseout: function qButton_e_onmouseout(e){e=getEvent(e);
			var o=e.target,os=o.style; os.backgroundColor=o._bk
			qSetOpacity(o, 0.9)
		}
    }
    
   
}


/*************************
	qFloatElem
*/

qFloatElem = {
	instances: []
	
  // Public Methods
    ,define: function qflt_define(oFlt, jOpt){
		var t=this,os=oFlt.style,oFltCtr,aInst=t.instances;jOpt=jOpt?jOpt:{}
		if( !(oFltCtr=getElem("qFloatElems")) ){
			$( oFltCtr=_d.createElement("div") )
				.attr({id: "qFloatElems"})
				.css("position", "absolute")
				.css("top", "1px")
			_d.body.appendChild(oFltCtr)
		}
		oFltCtr.appendChild(oFlt)
		$(oFlt)
			.css({position: "absolute", visibility: "hidden"})
			.bind("mouseover",t.e_mouseover)
			.bind("mouseout",t.e_mouseout)
			.bind("mousedown",t.e_mousedown)
//			.bind("mousemove",function flt_e_mousemove(e){pc("oFlt = "+this.id)})
			
		oFlt.jOpt=jOpt
		oFlt.fltPar = jOpt.fltPar
	  // Add Methods
		oFlt.open = t.priv_open
		oFlt.close = t.priv_close
		oFlt.startClose = t.priv_startClose
		oFlt._cto = t.priv_cto
		oFlt.isOpen = function qfe_isOpen(){ return this.style.visibility==="hidden"?false:true }
		aInst.p(oFlt)

		if(isUndef(oFlt.id) || s$(oFlt.id).trim()==="")oFlt.id="qfltElem"+aInst.length;

//pc("aInst.length = "+aInst.length)
		if(aInst.length==1){
			_w._aDoc_MD_Ev.p("qFloatElem.e_doc_mousedown")
		}
		
	}
	
  // Private Methods
/* todo:
	- Allow for positioning inside box. Eg. Inner Top Left ITL, Inner Top Right ITR, Inner Center IC...
*/
    ,priv_open: function qfe_open(jOpt){
 		var 
 			o=this,h=qHtml,qfe=qFloatElem
 		   ,os=o.style,sPosn,bTL,bTR,bBL,bBR,x,y,v
 		   ,iDelay,widg,f,ofsX,ofsY,fp=o.fltPar,iZI,oPE,xyPE
 		;
//pc(
//     "\n o = "+o.id
//    +"\n o.isOpen = "+o.isOpen()
//    +"\n args:\n"+s$.pad(q$.dumpArgs())
//    +"\n stack:\n"+s$.pad(getStackTrace())
//);
		o.onlyForceClose = jOpt.onlyForceClose
 		oPE = agetParam_elem("jOpt", jOpt, "parent", true)

 		ofsX=isInt(v=jOpt.ofsX)?v:0
 		ofsY=isInt(v=jOpt.ofsY)?v:0
 		sPosn = agetParam("jOpt", jOpt, "position", false, true)
 		     if(sPosn===h.POS_TL)bTL = true
 		else if(sPosn===h.POS_TR)bTR = true
 		else if(sPosn===h.POS_BL)bBL = true
 		else if(sPosn===h.POS_BR)bBR = true
 		else qErr("Invalid Position: "+sPosn)
 		if(!sPosn)bBL=true
 		
 		xyPE=getElemPosition(oPE)
 		
 		x = xyPE.x+(bTL||bBL?0:oPE.offsetWidth)+ofsX
 		y = xyPE.y+(bTL||bTR?0:oPE.offsetHeight)+ofsY
 		
//pc(
//    "\n o.id = "+o.id
//   +"\n o.getWidget = "+o.getWidget
//   +"\n oPE.id = "+oPE.id
//   +"\n oPE.offsetWidth = "+oPE.offsetWidth+", oPE.offsetHeight = "+oPE.offsetHeight
//   +"\n x = "+x+", y = "+y
//   +"\n bBL = "+bBL+", bBR = "+bBR+", bTL = "+bTL+", bTR = "+bTR
//   +"\n sPosn = "+sPosn
//   +"\n xyPE = "+q$.dump(xyPE).replace(/\n/g, ", ")
//)
 	  /* Call Is Opening Event */
		if( isFunc(f=o.getWidget) ){
			widg=f();
			try { 
				widg.isOpening() 
			} catch(x){ 
				pc(debugDump("failed on widg.isOpening()", x)) 
			}
		}
 		
 		os.top=y+"px"
 		os.left=x+"px"
 		os.visibility="visible"
 		if(v=jOpt.fadeIn)
 			$(o).fadeIn(v)

 		o.openTS=q$.getTS()
 		if(fp){
 			iZI=parseInt(fp.style.zIndex)+1
			try { o.fltPar._cto() }catch(x){}
		}
		os.zIndex=((isInt(iZI))?iZI:200);

		if(!jOpt.noSelfClose){
			o.startClose({delay: (jOpt.closeDelay||1500), noCasc: jOpt.noCasc});
		}
		
		
		

		
	}
	,priv_cto: function qfe_cto(j){
		var oFlt=this;j=j?j:{}
//pc("oFlt =+"+oFlt.id+"\n Stack:\n"+getStackTrace())
		try{ clearTimeout(oFlt._qht[0]); oFlt._qht=null }catch(x){}
		if(!j.noCasc)try { oFlt.fltPar._cto() }catch(x){};
	}
    ,priv_close: function qfe_close(j){
 		var h=qHtml,qfe=qFloatElem,oFlt=this,f,widg,fp,iTS,v;
 		j=j?j:{};
 		
 		if(oFlt.onlyForceClose && !j.force){return}
 		
 		iTS=isNum(j.ts)?j.ts:-1
 		
 		
//pc(
//	 "oFlt = "+oFlt.id
//	+"\n visibility = "+oFlt.style.visibility
//    +"\n args:\n"+s$.pad(q$.dumpArgs())
//    +"\n oFlt._qht:\n"+s$.pad(oFlt._qht)
//);
 		
 	  /* Call Is Opening Event */
		if( isFunc(f=oFlt.getWidget) ){
			widg=f();
			try { 
				widg.isClosing(iTS)
			} catch(x){ 
				pc(debugDump("failed on widg.isClosing()", x)) 
			}
		}
 		
//pc("oFlt = +"+oFlt.id)
		if(v=j.fadeOut)
			$(oFlt).fadeOut(v)
 		else
 			hideElem(oFlt)
 		
 		if(isDef(fp=oFlt.fltPar)){
 			try{
	 			if(j.delayedCasc){fp.startClose(j)}
	 			if(j.casc){fp.close(j)}
	 		}catch(x){}
 		}
 		
 	}
    ,priv_startClose: function qfe_startClose(j){
 		var h=qHtml,qfe=qFloatElem,oFlt=this,iD,fp,iTSCall;
 		j=j?j:{};
 		iD=(isInt(v=j.delay)?v:750)
 		
 		if(oFlt.ieOpenDD)return
//pc(
//	 "oFlt = "+oFlt.id
//	+"\n visibility = "+oFlt.style.visibility
//    +"\n args:\n"+s$.pad(q$.dumpArgs())
//    +"\n stack:\n"+s$.pad(getStackTrace())
//);
 		oFlt._cto();
 		iTSCall=isNum(j.tsCall)?j.tsCall:q$.getTS()
 		oFlt._qht = [setTimeout("agetElem(\""+oFlt.id+"\").close({ts: "+iTSCall+"})",iD),iD,(_w.bDebug?debugDump(new Error()):"-")]
//return;
//pc(
//	"\n oFlt._qht = "+oFlt._qht
//   +"\n j.noCasc = "+j.noCasc
//)
 		if(!j.noCasc&&(fp=oFlt.fltPar)){
 			try { 
//pc(
//	 "\n fp = "+fp.id
//	+"\n oFlt = "+oFlt.id
//	+"\n Check = "+(fp==oFlt)
//);
 			
 			fp.startClose({delay: iD}) }catch(x){}
 		}
 	}
	
  // Events
  	,e_mouseover: function qfe_e_mouseover(e){
		var	oFlt=this;
//pc("oFlt = "+oFlt.id)		
		if(oFlt.ieOpenDD)oFlt.ieOpenDD.blur()
		qFloatElem.mkMDFE(oFlt)
		oFlt._cto()
		showElem(oFlt)
 	  /* Call Is MOV Event */
		if( isFunc(f=oFlt.getWidget) ){
			widg=f();
			try { 
				widg.fltMOV() 
			} catch(x){ 
//				pc(debugDump("failed on widg.isClosing()", x)) 
			}
		}
  	}
  	,e_mouseout: function qfe_e_mouseout(e){
//pc("called - this = "+this.id)
		var	oFlt=this,aLMDFE=qFloatElem.lastMDFlt||[];
//pc("oFlt = "+oFlt.id)
		if(aLMDFE.has(oFlt.id))qFloatElem.lastMDFlt=null;
		oFlt.startClose();
  	}
  	,e_mousedown: function qfe_e_mousedown(e){
		var	oFlt=this;
//pc("oFlt = "+oFlt.id)
		qFloatElem.mkMDFE(oFlt)
		oFlt._cto()
  	}
  	,e_doc_mousedown: function qfe_e_doc_mousedown(e){
//pc("called")
		setTimeout("qFloatElem.e_doc_mousedown_to()", (is.ie?1:200))
  	}
  	,mkMDFE: function qfe_mkMDFE(oFlt){
  		var oP;
		aLMDFE=qFloatElem.lastMDFlt=[]
		oP=oFlt;while(oP){aLMDFE.p(oP.id);oP=oP.fltPar};
  	}
  	,e_doc_mousedown_to: function qfe_e_doc_mousedown_to(){
  		var a=qFloatElem.instances,o,j,iD=50,aLMDE=qFloatElem.lastMDFlt||[],iTS=q$.getTS()
//pc(
//    "\n aLMDE = "+aLMDE
//   +"\n iTS = "+iTS
//);
  		
		for(var i=0;i<a.length;i++){o=a[i];j=o.jOpt;
			
//pc(	 "\n Loop at "+i+""
//    +"\n o = "+o
//    +"\n o.id = "+o.id
//    +"\n o._qht = "+o._qht
//    +"\n o.isOpen = "+o.isOpen()
//    +"\n o.openTS = "+o.openTS
//    +"\n open delay = "+(iTS-o.openTS)
//    +"\n gate = "+(aLMDE.has(o.id))
//);
			if(aLMDE.has(o.id))continue;
			if(!j.selfClose && o.isOpen() && (!o._qht||o._qht[1]>iD) && ((iTS-o.openTS)>500)){
//pc("Calling start close of (id) "+o.id)
				o.startClose({delay: iD})
			}
		}
  	}
  	,e_doc_keydown: function qfe_e_doc_keydown(e){
//pc("e = "+e)
  	}
}


/********************************
	qSelect Widget
 ********************************/
qSelectWidget_StaticMembers = {
	pub_constants: {/* No not name const or it will kill IE :( */
		 TYPE_listMulti: 	"listMulti"
		,TYPE_dropDown: 	"dropDown"
		,TYPE_popUpSingle: 	"popUpSingle"
		,TYPE_popUpMulti: 	"popUpMulti"
	}
	,other: {
		 instances: []	
		,priv_opened: null
		,CSS_Gen: {border: "1px solid #777777", fontSize: "80%", backgroundColor: "#FFFFEF", color: "navy"}
	    ,create: function qsw_st_create(oDiv, jOpt){
	   		var t=this,oSW
	   		oSW = new qSelectWidget(oDiv, jOpt)
	   		return oSW
		}
		,e_doc_keydown: function qsw_e_doc_keydown(e){
			var oOpened=qSelectWidget.priv_opened
			if(oOpened){
				/* todo - This is where we can handle keydown events for Selects (Nice to have feature =) */
//pc(
//     "\n oOpened = "+oOpened
//    +"\n e.keyCode = "+e.keyCode
//    +"\n e:\n"+s$.pad(q$.dump(e))
//);
			}
		}
	}
}
qSelectWidget=QWidget.extend({
	className :"qSelectWidget"
  // Constructor
	,base_constr :function qsw_base_constr(oDiv, jOpt){
//		pc(">>")
		var	t=this,aInst=qSelectWidget.instances,v
		try	{
			qObjAppend(t,qSelectWidget_StaticMembers.pub_constants)		
			t.priv_no=aInst.length; aInst.p(t); 
			t.base({instance:t,	name:"qsw_"+t.priv_no})
					
			t.type=jOpt.type
			if(t.type===t.TYPE_listMulti){
				t.isMulti=true
			}else if(t.type===t.TYPE_dropDown){
				t.isDD=true
				t.hasPopUp=true
			}else if(t.type===t.TYPE_popUpSingle || t.type===t.TYPE_popUpMulti){
				t.funcValChg=agetParam_func("jOpt", jOpt, "funcValChg", true)
				t.funcGetCurVal=agetParam_func("jOpt", jOpt, "funcGetCurVal", true)
				t.hasPopUp=true
				t.isMulti=(t.type===t.TYPE_popUpMulti)
				oDiv.getPopUp=function qsw_getPopUp(){ return t.priv_oListMain}
			} else
				qErr("Invalid qSW Type passed ("+t.type+")")
			
			if(!isElem(oDiv))qErr("oDiv is not an HTML Element!")
			
			t.ctnr=oDiv
			
			oDiv.__qsw=t
			oDiv.getWidget = function cal_getWidget(){return t}
			
		  // Process CSS Overrides
		    qObjAppend(t.cssGen, qSelectWidget.CSS_Gen);
		    if( (v=jOpt.cssGen) ){qObjAppend(t.cssGen,v)};
			
			t.selected=t.isMulti?[]:-1
			
			t.rows=agetParam_int("jOpt", jOpt, "rows", false)
			if(t.rows==-1)t.rows=6
			t.loadOptions=agetParam_arr("jOpt", jOpt, "options", false)
			t.priv_fltParent=jOpt.fltParent
			
			t.options=[]

			t.init()
			
			if(aInst.length==1){
				_w._aDoc_KD_Ev.p("qSelectWidget.e_doc_keydown")
			}
			
		}catch(exc){qErr(t.className+" Base	Constructor	Failed:	",exc)}
			
//		pc("<<")
	}

   ,rows: 1
   ,isMulti: false
   ,isDD: false
   ,hasPopUp: false
   ,selected: -1
   ,options: null
   ,priv_no: -1
   ,loadOptions: null
   ,closeDelay: 2000
   ,cssGen: {}
   ,CAL_IMG: {tag: "img", _style: "cursor: hand; cursor: pointer;	opacity: 0.5; filter: alpha(opacity=50)"}

   ,isOpening: function qsw_isOpening(){pc("called")
		var t=this,oO=qSelectWidget.priv_opened,opt
		if(oO){ oO.priv_oListMain.close() };
		qSelectWidget.priv_opened=t;
		
	  // Auto Scroll to Selection
	  	if(!t.isMulti){
			var a=t.options,iSel=-1;
			for(var i=0;i<a.length;i++){if(( opt=a[i] ).isSelected){iSel=i;break}}
	  		if(iSel>-1){
	  			iSel=iSel<3?0:iSel-2.5;
				t.priv_oListMain.scrollTop=(iSel*(t.priv_oListMain.getElementsByTagName("li")[0].offsetHeight))
			}
		}
		
	}
   ,isClosing: function qsw_isClosing(){
   		var t=this;qSelectWidget.priv_opened=null;
   	}
   ,init: function qsw_init(){
		var
			 t=this,h=qHtml
			,d,oM,o,sMsg="",oDiv,oList,oIFr
			,s="", opt,sMainId
		;
		try	{
			sMainId="elQSW"+t.priv_no
					
		  // Make To DD Box
			if(t.isDD){

				$( o=t.priv_oDivTop=_d.createElement("div") )
				 	.attr({
				 			id: sMainId+"_TopText"
				 		   ,style: "-moz-user-select: none; background-image: url('"+imagePath+"qSelectBoxBase.gif'); background-repeat: no-repeat; background-position: 101% center"//border: 1px solid #26518D; 
				 	})
				 	.addClass("QSW_TEXT")
				 	.css(t.cssGen)
				 	.html("(empty)")
					.bind("click", function qsw_ddimg_click(e){
						var oS=this;oFlt=t.priv_oListMain
						if(oFlt.isOpen())
							oFlt.close()
						else
							oFlt.open({parent: t.priv_oDivTop, position: qHtml.POS_BL, closeDelay: 2500, noCasc: true})				
					})

				$(t.ctnr).html("");t.ctnr.appendChild(t.priv_oDivTop)

//pc("t.priv_oDivTop = "+t.priv_oDivTop)
				
			}

			$( o=t.priv_oListMain=_d.createElement("ul") )
			 	.attr({id: sMainId+"_Main"})
			 	.addClass("QSW_MAIN").addClass("float")
			 	.css({
			 			visibility:(t.hasPopUp?"hidden":"visible")
			 		   ,paddingRight: ( (is.ie?(t.hasPopUp?18:0):0)+"px" )
			 		   ,height: (t.rows*(is.ie?1.35:1.4)+"em")
			 		   ,overflowY: "scroll"
			 	})
			 	.css(t.cssGen)
			o.__qsw=t

			if(t.isDD)$(o).css({borderTop: "0px"})
			o.getWidget = function qsw_getWidget(){return t}


			if(t.hasPopUp){
				qFloatElem.define(t.priv_oListMain,{fltPar: t.priv_fltParent})
			} else {
				t.ctnr.innerHTML=""
				t.ctnr.appendChild(t.priv_oListMain)
			}


			if( (a=t.loadOptions).length>0 ){
				for(var i=0;i<a.length;i++){r=a[i]
//pc(
//    "\n r = "+r
//   +"\n r.length = "+r.length
//)
					t.addOption(
						(
							r.length==1?
								new qSWOption(r[0]):
							r.length==2?
								new qSWOption(r[0],r[1]):
							r.length==3?
								new qSWOption(r[0],r[1],r[2]):
							qErr("Invalid number of Fields for qSWOption ("+r.length+"). r=("+r+")")
						)
						,true
					)
				}
				
				if(t.funcGetCurVal){
					var aVal = t.funcGetCurVal()
					aVal=isArray(aVal)?aVal:[aVal]
					for(var i=0;i<aVal.length;i++)t.setSelectedByVal(aVal[i], true)
				}
				
				t.rebuild()
			}
			
		}catch(x){qErr(x)}
	}
	,getFltElem: function qsq_getFltElem(){return this.priv_oListMain}
	,addOption: function qsw_addOption(qOpt, bNRB){
		var t=this,oOpt,v,sT,sV,bSel,a=t.options;
		a.p(qOpt)
		if(qOpt.isSelected){
			t.setSelected(a.length-1, bNRB)
		}
	}

	,setSelected: function qsw_setSelected(iS,bNRB){
//pc(
//     "\n args:\n"+s$.pad(q$.dumpArgs())
//    +"\n stack:\n"+s$.pad(getStackTrace())
//);
		var t=this,a=t.options,opt;
		iS=iS<0?-1:iS
		if(iS<0||iS>a.length-1){qErr("iS ("+iS+") is < -or- > than # options!")}
		opt=a[iS];
		if(!t.isMulti)
			t.clearSelected(true)
		opt.isSelected=true;
		if(!bNRB)t.rebuild()
	}
	,setSelectedByVal: function qsw_setSelectedByVal(sVal,bNRB){
		var t=this,a=t.options,opt;
//pc(
//	"\n t = "+t
//   +"\n Stack:\n"+s$.pad(getStackTrace())
//)
		for(var i=0;i<a.length;i++){opt=a[i]
//pc(
//	"\n sVal = "+sVal
//   +"\n opt.value = "+opt.value
//   +"\n opt = "+q$.dumpJson(opt).replace(/\n/g,", ")
//)
			if(opt.value===sVal){t.setSelected(i, bNRB); break}
		}
	}
	,clearSelected: function qsw_clearSelected(bNRB){
		var t=this,a=t.options,opt;
		for(var i=0;i<a.length;i++){opt=a[i]
			opt.isSelected=false;
		}
		if(!bNRB)t.rebuild()
	}
	,clearAll: function qsw_clearAll(){
		var t=this,a=t.options;
		t.options=null;
		t.options=[]
	}
	,getSelected: function qsw_getSelected(){
		var t=this,a=t.options,aR=[];
		for(var i=0;i<a.length;i++)
			if(( opt=a[i] ).isSelected)aR.p(opt);
		return aR
	}
	,getSelectedValue: function qsw_getSelectedValue(){
		var t=this,a=t.options,aR=[],aSel;
		aSel=t.getSelected()
		for(var i=0;i<aSel.length;i++)aR.p(aSel.value)
		return aR
    }
    ,rebuild: function qsw_rebuild(){
    	var t=this,qsw=t,a=t.options,aR=[],aSel,oL=t.priv_oListMain,o,opt,oCL;
		oL.innerHTML=""
//pc("aa")
		var sH="",aC
		for(var i=0;i<a.length;i++){opt=a[i]; sH+="\n<li class='QSW_TEXT QSW_OPTTEXT"+(opt.isSelected?" QSW_OPT_SEL":"")+"'>"+opt.text+"</li>"}
		//pc("ab")
		oL.innerHTML=sH
		aC=oL.getElementsByTagName("li")
		//pc("ad")
		for(var i=0;i<a.length;i++){opt=a[i]; o=aC[i]
			$( o )
				.attr({ind: i})
			  // Events
				.bind("click", t.opt_click)
				.bind("mouseover", t.opt_mouseover)
				.bind("mouseout", t.opt_mouseout)
				.bind("mousedown", t.opt_mousedown)
				.bind("mouseup", t.opt_mouseup)
			  // Prevent Text Select in IE
				.bind("selectstart", t.opt_onSelectStart)
			;
			o.getQSW = t.opt_getQSW
		}

		if(t.hasPopUp){
			aOpts = t.getSelected()
	    	if(t.isDD){
	    		$(t.priv_oDivTop).css({width: (t.priv_oListMain.offsetWidth-(is.ie?0:8))+"px"})
//pc("opt = "+opt)
				if(aOpts.length==0)
					t.priv_oDivTop.innerHTML="-&nbsp;"
				else
					t.priv_oDivTop.innerHTML=aOpts[0].text
					
	    	}else{
				qsw.funcValChg(t.type==t.TYPE_popUpSingle?aOpts[0]:aOpts)
			}
	    }

    }
	,opt_mouseover: function qsw_opt_mouseover(e){var oS=this;
//pc(
//     "\n oS = "+oS
//    +"\n iS.ind = "+$(oS).attr("ind")
//);	
		
		$(oS).css({backgroundColor: "#316AC5", color: "white"})
	}
	,opt_mouseout: function qsw_opt_mouseout(e){var oS=this;$(oS).css({backgroundColor:"",color:""})}
	,opt_mousedown: function qsw_opt_mousedown(e){var oS=this;
//pc(
//     "\n oS = "+oS
//    +"\n iS.ind = "+$(oS).attr("ind")
//);	
		$(oS).css({backgroundColor: "#0A246A", color: "white"})
	}
	,opt_mouseup: function qsw_opt_mouseup(e){var oS=this;$(oS).css({backgroundColor: "#316AC5", color: "white"})}
	,opt_onSelectStart: function qsw_opt_onSelectStart(e){return false }
	,opt_click: function qsw_opt_click(e){
		var oS=this,qsw=oS.getQSW(),a=qsw.options,iInd=$(oS).attr("ind"),opt=a[iInd],bSel=opt.isSelected;
		if(!qsw.isMulti||!e.ctrlKey){ qsw.clearSelected(true) }
		if(qsw.isMulti&&bSel){
			opt.isSelected=false; qsw.rebuild()
		}else
			qsw.setSelected(iInd)
		if(qsw.hasPopUp && (!qsw.isMulti||!e.ctrlKey)){ qsw.priv_oListMain.close({delayedCasc: true, delay: 2000}) }
	}
	,opt_getQSW: function qsw_opt_getQSW(){return this.parentNode.__qsw}
    
    ,toString: function(){var t=this; return "["+t.className+" ("+this.priv_no+")]"}
	,constructor: function qSelectWidget(oDiv, j)	{this.base_constr(oDiv, j)}
	
});/*Inherit Static Members*/qObjAppend(qSelectWidget,qSelectWidget_StaticMembers.pub_constants);qObjAppend(qSelectWidget,qSelectWidget_StaticMembers.other)

function qSWOption(sText, sVal, bSel){
	var t=this,arg=arguments;
	if(arg.length==1){
		sVal=sText;
	} else if(arg.length==2){
		if(isBool(sVal)){
			bSel=(isBool(sVal)?sVal:false);
			sVal=sText;
		};
	};
	t.text=sText;
	t.value=sVal;
	t.isSelected=bSel;
};
qObjAppend(qSWOption.prototype,{isSelected: false,text: null,value: null})


/*
      Drag & Drop
 */
qDnD = {
      TYPE_STD : "standard"
     ,TYPE_MOVE : "move"
  /* Public */
  	 ,revokeDraggable: function dnd_revokeDraggable(item){
  	 	item.onmousedown=null	
  	 }
     ,makeDraggable: function dnd_makeDraggable(item, jOpts){
//        pc("called. Args:\n"+s$.pad(q$.dumpArgs()))
        var dnd=this,fStartCB, fDragCB, fDropCB, sType,v
        try {
            if(!isElem(item)) qErr("item is not an Elem");
            if(isJson(jOpts)){
                if((v=jOpts.startHandler)&&isFunc(v)){fStartCB=v}
                if((v=jOpts.dragHandler)&&isFunc(v)){fDragCB=v}
                if((v=jOpts.dropHandler)&&isFunc(v)){fDropCB=v}
                item.dnd_isMove = (jOpts.type==dnd.TYPE_MOVE);
                if(!item.dnd_isMove)item.dnd_isStandard=true
            }

            item.onmousedown = function dnd_item_onmousedown(e){e=e||_w.event;
                var
                    item=this,img, p
                ;
                try {

                    if(fStartCB && !fStartCB(e, item)){return}

                  // Capture Events
                    dnd.e_doc_onmousemove_bk = _d.onmousemove
                    dnd.e_doc_onmouseup_bk = _d.onmouseup
                    _d.onmousemove = dnd.e_doc_mouseMove;
                    _d.onmouseup   = dnd.e_doc_mouseUp;

                    dnd.origItem = item

                    if(item.dnd_isStandard){
//pc("is standard")
                        img=item.getElementsByTagName("img")[0]
                        p = item.parentNode

                        imgDrag = document.createElement("img");
                        imgDrag.src = img.src
                        imgDrag.height = img.height
                        imgDrag.width = img.width
                        imgDrag.style.zIndex = "999999"
                        imgDrag.style.cursor="move"


                        dnd.dragObject = imgDrag
                        dnd.dragImage = imgDrag

                        _d.body.appendChild(imgDrag);

                        dnd.mouseOffset = dnd.getMouseOffset(item, e);

//pc(
//    "\n getElemPosition(item) = "+q$.dump(getElemPosition(item)).replace(/\n/g,", ")
//   +"\n mouseOffset = "+q$.dump(dnd.mouseOffset).replace(/\n/g,", ")
//)

                        item.style.display="none"


//pc(
//    "\n dnd.dragObject = "+dnd.dragObject
//)
                    } else {
//pc("is move")
                        dnd.dragObject = item


                        imgDrag=(item.tagName=="IMG")?item:item.getElementsByTagName("img")[0]

                        dnd.dragImage = imgDrag

                        dnd.mouseOffset = dnd.getMouseOffset(item, e);

                        _d.body.appendChild(item);

//pc(
//    "\n dnd.dragObject = "+dnd.dragObject
//   +"\n dnd.origItem = "+dnd.origItem
//   +"\n dnd.mouseOffset = "+q$.dump(dnd.mouseOffset)
//)
                    }


//pc("dnd.origItem = "+dnd.origItem.id)

                    dnd.dragObject.style.position = "absolute";

                    dnd.dragObject.dragCB = fDragCB
                    dnd.dragObject.dropCB = fDropCB


                    dnd.e_doc_mouseMove(e)
                }catch(x){qErr(x)}

                return false;
            }
        }catch(x){qErr(x)}
    }
    ,getOrigItem: function dnd_getOrigItem(){ return qDnD.origItem }

    // Listeners
    ,e_doc_mouseMove: function dnd_e_doc_mouseMove(e){e=e||_w.event;
        var dnd=qDnD,o=dnd.dragObject,xyDragTL,xyDrop,item,fDragCB;

        try {
            xyDragTL=dnd.getDragXY(e)
            item=dnd.getOrigItem()

            if(o){
                os=o.style
//pc(
//    "Before:"
//   +"\n e = "+e
//   +"\n dnd.dragObject = "+o
//   +"\n dnd.dragObject.visbility = "+o.style.visibility
//   +"\n item = "+item.id
//   +"\n xyDragTL = "+q$.dump(xyDragTL).replace(/\n/g,", ")
//   +"\n mouseOffset = "+q$.dump(dnd.mouseOffset).replace(/\n/g,", ")
//   +"\n top = "+o.style.top
//   +"\n left = "+o.style.left
//   +"\n position = "+o.style.position
//)

                os.top      = xyDragTL.y+"px"
                os.left     = xyDragTL.x+"px"


                fDragCB=dnd.dragObject.dragCB
                if(fDragCB){
                    img=dnd.dragImage
                    xyDrop = {x:xyDragTL.x+(img.width/(is.ie?4:2)), y:xyDragTL.y+(img.height/(is.ie?4:2))}
                    dnd.dragObject.dragCB(e, xyDrop, xyDragTL, item);
                }

//pc(
//    "After:"
//   +"\n top = "+os.top
//   +"\n left = "+os.left
//   +"\n position = "+os.position
//)


                return false;
            }
        }catch(x){qErr(x)}
    }
    ,e_doc_mouseUp: function dnd_e_doc_mouseUp(e){e=e||_w.event;//pc("called")
        var dnd=qDnD,xyDropTL,xyDrop,item,fDropCB,img;

        try {
          // Restore Events
            _d.onmousemove = dnd.e_doc_onmousemove_bk
            _d.onmouseup = dnd.e_doc_onmouseup_bk

            if(dnd.dragObject){
                item = dnd.getOrigItem()

                if(item.dnd_isStandard){
                    item.style.display=""
                    dnd.dragObject.parentNode.removeChild(dnd.dragObject)
                }
//pc(
//    "\n item.offsetWidth  = "+item.offsetWidth
//   +"\n item.offsetHeight  = "+item.offsetHeight
//)

                fDropCB=dnd.dragObject.dropCB
                if(fDropCB){
                    xyDropTL=dnd.getDragXY(e)
                    img=dnd.dragImage
                    xyDrop = {x:xyDropTL.x+(img.width/(is.ie?4:2)), y:xyDropTL.y+(img.height/(is.ie?4:2))}
                    fDropCB(e, xyDrop, xyDropTL, item);
                }
                dnd.dragObject = null;

            }
        }catch(x){qErr(x)}

    }

    ,getDragXY: function dnd_getDragXY(e){
        var dnd=qDnD,xyMP=getMouseCoords(e)

        return {
            x:(xyMP.x - dnd.mouseOffset.x)
           ,y:(xyMP.y - dnd.mouseOffset.y)
        };
    }

  /* Private */
    ,getMouseOffset: function dnd_getMouseOffset(trg, e){e=e||_w.event;
        var dnd=this, dp, mp,xy
        dp    = getElemPosition(trg);
        mp  = getMouseCoords(e);
        xy = {x:mp.x - dp.x, y:mp.y - dp.y};
//pc(
//    "\n trg = "+trg
//   +"\n e   = "+e
//   +"\n dp  = "+q$.dump(dp).replace(/\n/g, ", ")
//   +"\n mp  = "+q$.dump(mp).replace(/\n/g, ", ")
//   +"\n xy  = "+q$.dump(xy).replace(/\n/g, ", ")
//)
        return xy;
    }

}
/*
    END Drag & Drop
*/

/* IE Background Img Flicker Fix */
try {if(is.ie)document.execCommand('BackgroundImageCache', false, true);} catch(e) {}